package com.spark.gaea.data.config;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.base.Preconditions;
import com.spark.gaea.config.service.easyzk.ConfigNode;
import com.spark.gaea.crypto.Decrypter;
import com.spark.gaea.utils.StringUtil;
import com.spark.gaea.utils.exception.GaeaRuntimeException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableTransactionManagement
public class DataSourceConfig {
	@Autowired
	Environment env;
	@Autowired(required = false)
	private ConfigNode applicationConfigNode;
	private static final String DEFAULT_MAX_ACTIVE = "250";

	@Bean
	public DruidDataSource dataSource() {
		final String url = Preconditions
				.checkNotNull(StringUtil.getProperty(this.applicationConfigNode, this.env, "db.url"), "db.url is null");
		final String username = Preconditions
				.checkNotNull(StringUtil.getProperty(this.applicationConfigNode, this.env, "db.username"),
						"db.username is null");
		final boolean isEncrypt = Boolean
				.parseBoolean(StringUtil.getProperty(this.applicationConfigNode, this.env, "db.encrypt", "false"));
		String password = Preconditions
				.checkNotNull(StringUtil.getProperty(this.applicationConfigNode, this.env, "db.password"),
						"db.password is null");
		final String maxActive = StringUtil.getProperty(this.applicationConfigNode, this.env, "db.maxActive", "250");
		final DruidDataSource dataSource = new DruidDataSource();
		dataSource.setUrl(url);
		dataSource.setUsername(username);
		if (isEncrypt) {
			try {
				password = Decrypter.decrypter(password);
			} catch (Exception e) {
				throw new GaeaRuntimeException("\u6570\u636e\u5e93\u5bc6\u7801\u89e3\u5bc6\u5931\u8d25", e);
			}
		}
		dataSource.setPassword(password);
		dataSource.setMaxActive(Integer.parseInt(maxActive));
		final List<Filter> filterList = new ArrayList<Filter>();
		filterList.add(this.statFilter());
		dataSource.setProxyFilters(filterList);
		return dataSource;
	}

	@Bean
	public DataSourceTransactionManager transactionManager() {
		final DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
		transactionManager.setDataSource(this.dataSource());
		return transactionManager;
	}

	@Bean
	public StatFilter statFilter() {
		final StatFilter filter = new StatFilter();
		filter.setSlowSqlMillis(10000L);
		filter.setLogSlowSql(true);
		return filter;
	}
}
